#!/usr/bin/env bash

set -e

BIN=bin

QUICKTESTS="tests/docstrings tests/issues tests/modsys tests/mono-binds tests/parser tests/regression tests/renamer"

function setup_external_tools() {
  [[ -x "$BIN/test-runner" || -x "$BIN/test-runner.exe" ]] && return
  cabal v2-install --install-method=copy --installdir="$BIN" test-lib
}

function show_usage() {
  cat << EOM
Usage: $0 COMMAND COMMAND_OPTIONS
Available commands:
  run                          Run Cryptol
  build                        Build Cryptol
  haddock                      Generate Haddock documentation
  test                         Run some tests (may take a while)
  quick-test                   Like "test" but run fewer tests by default
  set-test-output              Copy test results to expected results
  rpc-test                     Run RPC server tests
  rpc-docs                     Check that the RPC documentation is up-to-date
  exe-path                     Print the location of the local executable
  check-docs                   Check the exercises embedded in the documentation
EOM
}

if [ "$#" == "0" ]; then
  show_usage
  exit 1
fi

COMMAND=$1
shift

case $COMMAND in
  run) cabal -v0 v2-exec cryptol -- $* ;;

  build)
    echo Building Cryptol

    # XXX: This is a workaround the fact that currently Cabal
    # will not rebuild this file, even though it has TH code, that
    # depends on the environment.  For now, we temporarily modify the
    # file, then build, then revert it back, then build once more.

    dirty_string="-- Last build $(date)"
    echo "$dirty_string" >> src/GitRev.hs

    cabal v2-build "$@" exe:cryptol

    sed -i.bak "/^-- Last build/d" src/GitRev.hs
    rm -f src/GitRev.hs.bak

    cabal v2-build "$@" exe:cryptol
    ;;

  haddock) echo Building Haddock documentation && cabal v2-haddock ;;

  quick-test)
    echo Running quick tests
    setup_external_tools
    $BIN/test-runner --ext=.icry \
      --exe=cabal \
      -F v2-run -F -v0 -F exe:cryptol -F -- -F -b \
      $QUICKTESTS
    ;;

  test)
    echo Running tests
    setup_external_tools
    if [ "$#" == "0" ]; then
      if cabal v2-exec cryptol -- -v | grep -q 'FFI enabled'; then
        TESTS=(tests/*)
      else
        GLOBIGNORE="tests/ffi"
        TESTS=(tests/*)
        unset GLOBIGNORE
      fi
    else
      TESTS=("$*")
    fi
    $BIN/test-runner --ext=.icry --env-ext=.env \
      --exe=cabal \
      -F v2-run -F -v0 -F exe:cryptol -F -- -F -b \
      "${TESTS[@]}"
    ;;

  set-test-output)
    DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
    FILE=$(mktemp)
    pushd "$DIR/output"
    find . -name '*.stdout*' -print0 | tar czf "$FILE" --null -T -
    popd
    tar xzvf "$FILE"
    rm -rf "$FILE"
  ;;

  rpc-test)
    echo Running RPC server tests
    DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
    $DIR/cryptol-remote-api/run_rpc_tests.sh
    ;;

  rpc-docs)
    echo "Checking cryptol-remote-api docs (Cryptol.rst) are up-to-date with server"
    DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
    $DIR/cryptol-remote-api/check_docs.sh
    ;;

  check-docs)
    cabal v2-build exe:check-exercises
    find ./docs/ProgrammingCryptol -name '*.tex' -print0 | xargs -0 -n1 cabal v2-exec -v0 check-exercises
    ;;

  help) show_usage && exit 0 ;;

  exe-path) cabal v2-exec which cryptol ;;

  *) echo "Unrecognized command: $COMMAND" && show_usage && exit 1 ;;
esac
